#include "trees.h"
#include "path.h"
#include "dynamic-tree.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

template <class V, class E>
Trees::DynamicPathTree<V,E>::DynamicPathTree(const V& val) : DynamicTree<V,E>(val), m_dParent(NULL)
{
}

template <class V, class E>
Trees::DynamicTree<V,E>* Trees::DynamicPathTree<V,E>::Parent() const
{
	Path<V,E>* path = GetPath();
	if ( path->Tail() == this )
	{
		return DParent();
	}
	return After();
}

template <class V, class E>
Trees::DynamicTree<V,E>* Trees::DynamicPathTree<V,E>::Root() const
{
#ifdef TREE_DEBUG
	cerr << "Root(" << this->Value() << ") >>>" << endl;
#endif	
	DynamicTree<V,E>* root = Expose()->Tail();
#ifdef TREE_DEBUG
	cerr << "Root(" << this->Value() << ") <<< return " << root->Value() << endl;
#endif
	return root;
}

template <class V, class E>
const E Trees::DynamicPathTree<V,E>::Cost() const
{
	Path<V,E>* path = GetPath();
	if ( path->Tail() == this )
	{
		return DCost();
	}
	return PCost();
}

template <class V, class E>
Trees::DynamicTree<V,E>* Trees::DynamicPathTree<V,E>::MinCost() const
{
	return Expose()->PMinCost();
}

template <class V, class E>
void Trees::DynamicPathTree<V,E>::Update(const E& x)
{
	Expose()->PUpdate(x);
}

template <class V, class E>
void Trees::DynamicPathTree<V,E>::Link(Trees::DynamicTree<V,E>* otherRoot, const E& x)
{
	DynamicPathTree<V,E>* otherPathTreeRoot = dynamic_cast<DynamicPathTree<V,E> *>(otherRoot);
	otherPathTreeRoot->GetPath()->Concatenate(Expose(), x);
}

template <class V, class E>
const E Trees::DynamicPathTree<V,E>::Cut()
{
#ifdef TREE_DEBUG
	std::ostringstream stringStream;
	stringStream << "Cut(" << this->Value() << ")";
	string logLabel = stringStream.str();
#endif	
	Expose();
	Path<V,E>* p;
	Path<V,E>* q;
	E x, y;
	Split(&p, &q, &x, &y);
	m_dParent = NULL;
}

template <class V, class E>
void Trees::DynamicPathTree<V,E>::Evert()
{
	Expose()->Reverse();
	m_dParent = NULL;
}

template class Trees::DynamicPathTree<int,int>;

template class Trees::DynamicPathTree<int, Trees::EdgeInfo<int> >;
